﻿using System;
using System.Linq;
using LINQPad.Extensibility.DataContext;
using LINQPad.OpenAccess.Settings;

namespace LINQPad.OpenAccess.Services.Descriptors
{
    /// <summary>
    ///  Default <see cref="IConnectionDescriptor" />.
    /// </summary>
    public class DefaultConnectionDescriptor : ConnectionDescriptorBase
    {
        #region Protected

        #region - Functions

        /// <summary>
        /// Gets the name of the backend.
        /// </summary>
        /// <param name="driverSettings">The driver settings.</param>
        /// <returns>
        /// The name of the backend or <c>null</c>.
        /// </returns>
        protected virtual string GetBackendName( DriverSettings driverSettings )
        {
            BackendSettings backendSettings;
            if ( driverSettings == null
                    || null == ( backendSettings = driverSettings.Backend )
                    || backendSettings.IsDefault
                    || !backendSettings.Backend.HasValue )
                return null;

            return backendSettings.Backend.ToString( );
        }
        /// <summary>
        /// Gets the database description.
        /// </summary>
        /// <param name="connectionInfo">The connection info.</param>
        /// <param name="driverSettings">The driver settings.</param>
        /// <returns>
        /// The description or <c>null</c>.
        /// </returns>
        protected virtual string GetDatabaseDescription( IConnectionInfo connectionInfo, DriverSettings driverSettings )
        {
            string description = null;
            if ( driverSettings.Connection != null )
                description = this.GetDescriptionForCustomConnection( connectionInfo, driverSettings.Connection );
            if ( String.IsNullOrWhiteSpace( description ) )
            {
                var databaseInfo = connectionInfo.DatabaseInfo;
                if ( databaseInfo != null )
                    description = databaseInfo.GetDatabaseDescription( );
            }
            return description;
        }
        /// <summary>
        /// Gets the description for the custom connection.
        /// </summary>
        /// <param name="connectionInfo">The connection info.</param>
        /// <param name="connectionSettings">The connection settings.</param>
        /// <returns>
        /// The description for the custom connection or <c>null</c>.
        /// </returns>
        protected virtual string GetDescriptionForCustomConnection( IConnectionInfo connectionInfo, ConnectionSettings connectionSettings )
        {
            return null;
        }

        #endregion

        #endregion

        #region Public

        #region - Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultConnectionDescriptor" /> class.
        /// </summary>
        public DefaultConnectionDescriptor( int priority = Int32.MinValue )
            : base( priority ) { }

        #endregion

        #endregion

        #region IConnectionDescriptor Members

        /// <summary>
        /// Determines whether this instance is able to describe the specified connection.
        /// </summary>
        /// <param name="connectionInfo">The connection info.</param>
        /// <param name="driverSettings">The driver settings.</param>
        /// <returns>
        ///   <c>true</c> if this instance is able to describe the specified connection; otherwise, <c>false</c>.
        /// </returns>
        public override bool CanDescribe( IConnectionInfo connectionInfo, DriverSettings driverSettings )
        {
            return connectionInfo != null && driverSettings != null;
        }
        /// <summary>
        /// Describes the specified connection.
        /// </summary>
        /// <param name="connectionInfo">The connection info.</param>
        /// <param name="driverSettings">The driver settings.</param>
        /// <returns>
        /// The description.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public override string Describe( IConnectionInfo connectionInfo, DriverSettings driverSettings )
        {
            var contextTypeName = this.GetContextTypeName( connectionInfo );
            var backendName = this.GetBackendName( driverSettings );
            var databaseDescription = this.GetDatabaseDescription( connectionInfo, driverSettings );

            if ( !String.IsNullOrWhiteSpace( backendName ) && !String.IsNullOrWhiteSpace( databaseDescription ) )
                return String.Format( "{0} ({1}) [{2}]", contextTypeName, databaseDescription, backendName );
            else if ( !String.IsNullOrWhiteSpace( backendName ) )
                return String.Format( "{0} [{1}]", contextTypeName, backendName );
            else if ( !String.IsNullOrWhiteSpace( databaseDescription ) )
                return String.Format( "{0} ({1})", contextTypeName, databaseDescription );
            return contextTypeName;
        }

        #endregion
    }
}
